#pragma once
#include "Points.h"
int click_count =0;
int x_old,y_old;
int x_0,y_0;
Lines lines;
char c;
bool valued_point[100][100];
Points point_list[100];
class ImageProcess
{
public:
	
	int num_particles_width; // number of particles in "width" direction
	int num_particles_height;
	IplImage* image;
	IplImage* image_base;
	float scale;
	int width,height;
public:

	ImageProcess(void);
	ImageProcess(char* name,Lines line,float width, float height, int num_particles_width, int num_particles_height) ;
	~ImageProcess(void);
	void ShowImage();
	void Save(char *filename);
};
void ImageProcess::Save(char *filename)
{
	
	ofstream f;

	f.open(filename,ios::out);
	f << num_particles_width << " " << num_particles_height << endl;
	f << width << " " << height << endl;
	for(int i =0;i<num_particles_height;i++)
	{
		for(int j =0;j<num_particles_width;j++)
		{
			f << valued_point[j][i] << " ";
		}
		f << endl;
	}
	f.close();
	lines.Save(filename);
	f.open(filename,ios::app);
	for(int i =0;i<lines.n;i++)
	{
		f << point_list[i].n << " ";
		for(int j=0;j<100;j++)
			if(point_list[i].p[j].x != -1)
				f << point_list[i].p[j].x << " " << point_list[i].p[j].y << " ";
		f << endl;
	}
	f.close();
}
void ImageProcess::ShowImage()
{
	int x,y;
	//cout << " "<<num_particles_width;
	image = cvCloneImage(image_base);
	for(int i=0; i<num_particles_width; i++)
			for(int j=0; j<num_particles_height; j++)
			{
				x = i*x_step + 0.5;
				y = j*y_step+ 0.5;
				if(valued_point[i][j] == true)
					cvCircle(image,cvPoint(x,y),2,cvScalar(0,0,255),3);	
			}
	for(int i =0;i<lines.n;i++)
	for(int j=0;j<100;j++)
	{
		if(point_list[i].p[j].x != -1)
		{
			x = point_list[i].p[j].x*x_step + 0.5;
			y = point_list[i].p[j].y*y_step+ 0.5;
			cvCircle(image,cvPoint(x,y),2,cvScalar(280,100,255),6);	
		}
	}
	lines.DrawAllLine(image);
	cvCircle(image,cvPoint(x_old*x_step,y_old*y_step),2,cvScalar(0,255,0),6);


	cvShowImage("test",image);
}
void my_mouse_callback( int event, int x, int y, int flags, void* param ){
	ImageProcess* prcess = (ImageProcess*) param;

	
	switch( event )
	{
		case CV_EVENT_MOUSEMOVE: 
			
			break;

		case CV_EVENT_LBUTTONDOWN:
			if(editline == false)
			{
				if(click_count ==0)
				{

					x_old = x/x_step + .5;
					y_old = y/y_step+ .5;
					x_0 = x_old;
					 y_0 = y_old;
				}
				else
				{
					lines.Add(x_old,y_old,x/x_step+0.5,y/y_step+0.5);
					x_old  = x/x_step+.5;
					y_old  = y/y_step+ .5;
				}
				click_count++;
				cvCircle(prcess->image,cvPoint(x_old*x_step,y_old*y_step),2,cvScalar(255,0,255),5);
				//cvShowImage("test",prcess->image);
				prcess->ShowImage();
			}
			else
			{
				point_list[index_edit].Update( x/x_step + .5,y/y_step+ .5);
				prcess->ShowImage();
			}
			break;
		case CV_EVENT_RBUTTONDOWN:
			valued_point[(int)(x/x_step + .5)][(int)(y/y_step + .5)] = !valued_point[(int)(x/x_step + .5)][(int)(y/y_step + .5)];
			//cvShowImage("test",prcess->image);
			prcess->ShowImage();
			break;
		
		case CV_EVENT_LBUTTONUP:
			
			break;
	}
}
ImageProcess::ImageProcess(char* name,Lines line,float width, float height, int num_particles_width, int num_particles_height) 
{
	editline = false;
	//image = cvLoadImage("a.png");
	this->num_particles_height = num_particles_height;
	this->num_particles_width = num_particles_width;
	this->height = height;
	this->width = width;
	image_base = cvLoadImage("a.png");
	image = cvCloneImage(image_base);
	float scale_x = image->width*1.0f/width;
	float scale_y = image->height*1.0f/height;
	scale = (scale_x > scale_y) ?scale_x:scale_y;
	//IplImage* image2 = cvCreateImage(cvSize(image->width/scale,image->height/scale),8,3);

	//cvResize(image,image2,1/scale);

	cvShowImage("image",image);
	//cvShowImage("image2",image2);

	
	//int new_width = width*scale;
	//int new_height = height*scale;
	int x,y;
	x_step = width/(float)num_particles_width  *scale;
	y_step = height/(float)num_particles_height  *scale;

	cout << x_step;
	for(int i=0; i<num_particles_width; i++)
			for(int j=0; j<num_particles_height; j++)
			{
				x = width * (i/(float)num_particles_width)            *scale;
				y = height * (j/(float)num_particles_height)          *scale;
				if(x > image->width || y > image->height)
					valued_point[i][j] = false;
				else
				{
					int c = image->imageData[y*image->widthStep + x*image->nChannels];
					if(c == 0)
						valued_point[i][j] = false;
					else
						valued_point[i][j] = true;
				}

				if(valued_point[i][j] == true)
					cvCircle(image,cvPoint(x,y),2,cvScalar(0,0,255),3);
			}

	cvShowImage("test",image);
	cvSetMouseCallback( "test", my_mouse_callback, this);
	while(true)
	{
		c = cvWaitKey();
		if(c == 'e')
			break;
		if(c == 'd')
		{
			click_count =0;
			lines.Add(x_old,y_old,x_0,y_0);
			//lines.ShowAll();
			lines.DrawAllLine(image);
			cout <<"DOne";
		}
		if(c == 's')
		{
			Save("a.txt");
			
		}
		if(c == 'm')
		{
			editline = !editline;
			index_edit =0;
			ShowImage();
		}
		if(c == 'n' && editline==true)
		{
			
			index_edit++;
			if(index_edit == lines.n)
				index_edit =0;
			ShowImage();
		}

	}
}
ImageProcess::ImageProcess(void)
{
	editline = false;
}
ImageProcess::~ImageProcess(void)
{
}